package com.business.plat.sa.controller;

import java.io.File;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.util.WebUtils;

import com.business.dto.AuthUser;
import com.google.gson.reflect.TypeToken;
import com.oxygen.components.ServletUploadFileItem;
import com.oxygen.constants.Constant;
import com.oxygen.enums.ApiMethodEnum;
import com.oxygen.enums.ApiServerEnum;
import com.oxygen.enums.BackendApiMethodEnum;
import com.oxygen.util.HttpClientUtil;
import com.oxygen.util.JsonUtil;
import com.oxygen.util.SimpleTokenUtil;
import com.oxygen.web.SuperDispatcherServlet;
import com.oxygen.web.WebHelper;

public class BaseAction {

	protected static final String SESSION_ADMIN_DTO = "adminDto";

	@Value("${dounaba.user.api.server}")
	private String userApiServer;

	@Value("${dounaba.content.api.server}")
	private String contentApiServer;

	@Value("${dounaba.commonservice.api.server}")
	private String commonserviceApiServer;

	@Value("${dounaba.activity.api.server}")
	private String activityApiServer;

	@Value("${dounaba.report.api.server}")
	private String reportApiServer;
	
	@Value("${dounaba.product.api.server}")
	private String productApiServer;

	@Value("${dounaba.api.key}")
	private String apiKey;

	@Value("${dounaba.api.secert}")
	private String apiSecert;

	@Value("${file.server.tempDir}")
	protected String fileServerTempDir;

	protected void setOperator(Map<String, Object> appendMap, HttpServletRequest req) {
		AuthUser adminSession = this.getSessionAdmin(req);
		if (adminSession != null) {
			appendMap.put("operator_id", adminSession.getId());
			appendMap.put("operator_name", adminSession.getUsername());
		}
	}

	protected boolean isLogon(HttpServletRequest req) {
		if (this.getSessionAdmin(req) != null) {
			return true;
		}
		return false;
	}

	protected Integer getSessionAdminId(HttpServletRequest req) {
		AuthUser adminDto = this.getSessionAdmin(req);
		if (adminDto != null) {
			return adminDto.getId();
		}
		return null;
	}

	protected AuthUser getSessionAdmin(HttpServletRequest req) {
		AuthUser adminDto = (AuthUser) WebUtils.getSessionAttribute(req, SESSION_ADMIN_DTO);
		return adminDto;
	}

	protected String callApi(BackendApiMethodEnum apiMethodEnum, Map<String, Object> appendMap, HttpServletRequest req) {
		return this._callApi(apiMethodEnum.getCode(), apiMethodEnum.getApiServer(), appendMap, req);
	}

	protected String callApi(ApiMethodEnum apiMethodEnum, Map<String, Object> appendMap, HttpServletRequest req) {
		return this._callApi(apiMethodEnum.getCode(), apiMethodEnum.getApiServer(), appendMap, req);
	}

	private String _callApi(String functionCode, ApiServerEnum apiServer, Map<String, Object> appendMap, HttpServletRequest req) {
		Map<String, Object> reqParamMap = null;
		if (req != null) {
			reqParamMap = WebHelper.buildParamMapFromRequest(req);
			this.setOperator(reqParamMap, req);
		} else {
			reqParamMap = new HashMap<String, Object>();
		}
		if (appendMap != null && appendMap.size() > 0) {
			reqParamMap.putAll(appendMap);
		}
		reqParamMap.put(Constant.API_KEY, apiKey);
		String token = SimpleTokenUtil.buildToken(reqParamMap, functionCode, apiSecert);
		reqParamMap.put(Constant.ACCESS_TOKEN, token);
		if (req != null) {
			reqParamMap.put(Constant.REQUEST_IP, WebHelper.getRequestIp(req));
		}

		Map<String, Object> functionCodeMap = new HashMap<String, Object>();
		functionCodeMap.put(functionCode, reqParamMap);

		Map<String, Object> dataMap = new HashMap<String, Object>();
		dataMap.put(Constant.DATA, JsonUtil.objectToJson(functionCodeMap, Map.class));

		HttpClientUtil clientUtil = new HttpClientUtil();
		Map<String, String> head = new HashMap<String, String>();
		int port = SuperDispatcherServlet.getlocalPort();
		head.put("referer", "backend/" + port);
		clientUtil.setHttpSetting(head);
		String retJson = clientUtil.doHttpPost(this.getApiServeUrl(apiServer), dataMap);
		return retJson;
	}

	protected String getRequestUrl(HttpServletRequest req) {
		String rquestUrl = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + req.getRequestURI();
		if (req.getServerPort() == 80) {
			rquestUrl = req.getScheme() + "://" + req.getServerName() + req.getRequestURI();
		}
		return rquestUrl;
	}

	protected String getApiServeUrl(ApiServerEnum apiServerEnum) {
		if (ApiServerEnum.user.equals(apiServerEnum)) {
			return this.userApiServer;
		} else if (ApiServerEnum.content.equals(apiServerEnum)) {
			return this.contentApiServer;
		} else if (ApiServerEnum.activity.equals(apiServerEnum)) {
			return this.activityApiServer;
		} else if (ApiServerEnum.commonservice.equals(apiServerEnum)) {
			return this.commonserviceApiServer;
		} else if (ApiServerEnum.report.equals(apiServerEnum)) {
			return this.reportApiServer;
		}
		else if (ApiServerEnum.product.equals(apiServerEnum)) {
			return this.productApiServer;
		}
		return null;
	}

	/**
	 * 调用API并输出json
	 * 
	 * @param ApiMethodEnum
	 *            API FUNCTION CODE
	 * @param appendMap
	 *            附加参数
	 * @param req
	 *            http请求
	 * @param rsp
	 *            http响应
	 * @return
	 * @author Daniel
	 */
	protected String callApiAndOutput(BackendApiMethodEnum apiMethodEnum, Map<String, Object> appendMap, HttpServletRequest req, HttpServletResponse rsp) {
		String retJson = this.callApi(apiMethodEnum, appendMap, req);
		return WebHelper.outputJson(retJson, rsp);
	}

	protected String outputJson(String json, HttpServletResponse rsp) {
		return WebHelper.outputJson(json, rsp);
	}

	/**
	 * 文件上传对象
	 * 
	 * @param request
	 * @param fileSizeMax
	 * @return
	 * @throws Exception
	 */
	protected ServletUploadFileItem getUploadFileItem(final HttpServletRequest request, long fileSizeMax) throws Exception {
		// 创建临时文件夹
		File dirTempFile = new File(this.fileServerTempDir);
		if (!dirTempFile.exists()) {
			dirTempFile.mkdirs();
		}
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setSizeThreshold(10 * 1024 * 1024); // 设定使用内存超过5M时，将产生临时文件并存储于临时目录中。
		factory.setRepository(dirTempFile); // 设定存储临时文件的目录。
		ServletUploadFileItem upload = new ServletUploadFileItem();
		upload.setFileItemFactory(factory);
		upload.setFileSizeMax(fileSizeMax * 1024 * 1024);
		upload.setHeaderEncoding("utf-8");
		upload.setProgressListener(new ProgressListener() {
			@Override
			public void update(long pBytesRead, long pContentLength, int pItems) {
				Map<String, Long> retMap = new HashMap<String, Long>();
				retMap.put("loaded", pBytesRead);
				retMap.put("total", pContentLength);
				// System.out.println("loaded=" + pBytesRead + "	total=" +
				// pContentLength + "	pItems=" + pItems);
				String uploaderLocation = request.getParameter("uploaderLocation");
				// request.getSession().setAttribute("ProgressListenerJson",
				// retMap);
				WebUtils.setSessionAttribute(request, "ProgressListener-" + uploaderLocation, retMap);
			}
		});
		upload.parse(request);
		return upload;
	}

	protected String outputApiMsg(BackendApiMethodEnum apiMethodEnum, boolean isSuccess, String msg, HttpServletResponse rsp) {
		Map<String, Map<String, Object>> retMap = new HashMap<String, Map<String, Object>>();
		Map<String, Object> msgMap = new HashMap<String, Object>();
		msgMap.put("isSuccess", isSuccess);
		msgMap.put("msg", msg);
		retMap.put(apiMethodEnum.getCode(), msgMap);
		String retJson = JsonUtil.objectToJson(retMap, new TypeToken<Map<String, Map<String, Object>>>() {
		}.getType());
		return WebHelper.outputJson(retJson, rsp);
	}

	protected String buildJsonForUpdateOrder(HttpServletRequest req) {
		String ids = req.getParameter("ids");
		String orders = req.getParameter("orders");
		String[] idArr = ids.split(",");
		String[] orderArr = orders.split(",");
		List<Map<String, Integer>> jsonList = new ArrayList<Map<String, Integer>>();
		for (int i = 0; i < idArr.length; i++) {
			Map<String, Integer> dataMap = new HashMap<String, Integer>();
			dataMap.put("id", Integer.valueOf(idArr[i]));
			dataMap.put("order", Integer.valueOf(orderArr[i]));
			jsonList.add(dataMap);
		}
		Type type = new TypeToken<List<Map<String, Integer>>>() {
		}.getType();
		return JsonUtil.objectToJson(jsonList, type);
	}
}
